package com.ideal.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ideal.config.Constant;
import com.ideal.dto.DictInfoDto;
import com.ideal.dto.ResultDto;
import com.ideal.dto.config.req.*;
import com.ideal.dto.config.res.FileConfigPageRsqDto;
import com.ideal.enums.FileTypeEnum;
import com.ideal.enums.GlobalExceptionEnum;
import com.ideal.model.Config;
import com.ideal.model.ConfigVersion;
import com.ideal.model.RConfigVersion;
import com.ideal.model.SysTreeDict;
import com.ideal.service.*;
import com.ideal.service.access.FileCommonAccessService;
import com.ideal.util.FileUtils;
import com.ideal.util.RandomUtil;
import com.ideal.util.file.IniUtil;
import com.ideal.util.file.PropertiesUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author songfz
 * @Description
 * @Date 2022/7/19
 */
@Service
public class AggregateConfigServiceImpl implements IAggregateConfigService {

    @Autowired
    private IConfigService configService;
    @Autowired
    private IConfigVersionService configVersionService;
    @Autowired
    private IRConfigVersionService irConfigVersionService;

    @Autowired
    private ISysTreeDictService sysTreeDictService;

    @Autowired
    private FileCommonAccessService fileCommonAccessService;

    /**
     * 保存配置文件数据
     * @param configDto
     * @return
     * @throws UnsupportedEncodingException
     */
    @Override
    @Transactional
    public String insertConfig(FileConfigDto configDto) throws UnsupportedEncodingException {
        final List<DictInfoDto> globalNoteList = sysTreeDictService.dictChildDetail(Constant.TREE_DICT_GLOBAL_NOTE_KEY);

        final Integer count = configService.existEnNameAndRule(configDto.getFileEnName(), configDto.getRoleGroup());
        if (count > 0) {
            throw new RuntimeException(GlobalExceptionEnum.EXIST_DATA.getMsg());
        }
        Config config = configService.selectByConfigDto(configDto);
        if (Objects.isNull(config)) {

            config = new Config();
            config.setStatus(1L);
            config.setCreatedTime(new Date());
            BeanUtils.copyProperties(configDto, config);
            configService.insertConfig(config);
        }

        ConfigVersion configVersion = new ConfigVersion();
        BeanUtils.copyProperties(configDto, configVersion);
        configVersion.setConfigId(config.getId());
        configVersion.setUseStatus(0L);
        configVersion.setCreatedTime(new Date());
        //非展示类型
        if (config.getBizType() != 2) {

            configVersion.setContent(FileUtils.readContext(configDto.getFileList().get(0).getFileUrl(),globalNoteList));
        }
        configVersion.setFileUrl(configDto.getFileList().get(0).getFileUrl());
        String versionNo = RandomUtil.versionNo();
        configVersion.setVersion(versionNo);
        configVersionService.insertConfigVersion(configVersion);
        RConfigVersion rConfigVersion = new RConfigVersion();
        rConfigVersion.setConfigId(config.getId());
        rConfigVersion.setConfigVersionId(configVersion.getId());
        irConfigVersionService.insertRConfigVersion(rConfigVersion);
        return versionNo;
    }

    @Override
    public PageInfo page(FileConfigPageReqDto pageReqDto) {

        PageHelper.startPage(pageReqDto.getPageNum(), pageReqDto.getPageSize());
        List<FileConfigPageRsqDto> list = this.configService.findByPageParams(pageReqDto);
        for (FileConfigPageRsqDto fileConfigPageRsqDto : list) {
            final ResultDto resultDto = sysTreeDictService.getFileState(fileConfigPageRsqDto.getFileEnName());

            if (resultDto.getCode()==0) {
                fileConfigPageRsqDto.setSwitchState(Integer.valueOf(resultDto.getData().toString()));
            }else {
                fileConfigPageRsqDto.setSwitchState(1);
            }
        }
        PageInfo<FileConfigPageRsqDto> info = new PageInfo<>(list);
        return info;
    }

    /**
     * 已发布配置替换功能
     * @param reqDto
     * @return
     */
    @Override
    @Transactional
    public String modConfig(ConfigModReqDto reqDto) throws UnsupportedEncodingException {
        Config config = configService.selectConfigById(reqDto.getConfigId());
        String version = RandomUtil.versionNo();
        if (Objects.nonNull(config) && config.getStatus() == 3) {
            ConfigVersion configVersion = configVersionService.findUseVersionByConfigId(reqDto.getRoleGroup(),reqDto.getConfigId());
            configVersion.setDisuseCause(reqDto.getDisuseCause());
            configVersion.setUpdatedTime(new Date());
            configVersionService.updateConfigVersion(configVersion);
            final List<DictInfoDto> globalNoteList = sysTreeDictService.dictChildDetail(Constant.TREE_DICT_GLOBAL_NOTE_KEY);
            ConfigVersion newVersion = new ConfigVersion();
            newVersion.setConfigId(config.getId());
            newVersion.setUseStatus(0L);
            newVersion.setCreatedTime(new Date());
            newVersion.setVersion(version);
            newVersion.setRoleGroup(reqDto.getRoleGroup());
            if (config.getBizType() != 2) {
                newVersion.setContent(FileUtils.readContext(reqDto.getFileInfo().getFileUrl(), globalNoteList));
            }
            newVersion.setRemark(reqDto.getRemark());
            newVersion.setFileUrl(reqDto.getFileInfo().getFileUrl());
            configVersionService.insertConfigVersion(newVersion);

            RConfigVersion rConfigVersion = new RConfigVersion();
            rConfigVersion.setConfigId(config.getId());
            rConfigVersion.setConfigVersionId(newVersion.getId());
            irConfigVersionService.insertRConfigVersion(rConfigVersion);
        }
        return version;
    }

    /**
     * 确认页面数据修改
     * @param fileContentModReqDto
     * @return
     */
    @Override
    public ResultDto updateConfigContent(FileContentModReqDto fileContentModReqDto) {
        String fileUrl = fileContentModReqDto.getFileUrl();
        if (fileUrl==null ||"".equals(fileUrl)){
            return ResultDto.fail("没有文件地址");
        }
        String[] split = fileUrl.split("\\.");
        if (split.length<2){
            return ResultDto.fail("文件名不正确");
        }
        String fileType = split[1];
        //excel格式
        if (FileTypeEnum.EXECL.getSubfix().equalsIgnoreCase(fileType)){

        } else if (FileTypeEnum.INI.getSubfix().equals(fileType)) {

            fileContentModReqDto.setContent(IniUtil.textToContext(fileContentModReqDto.getContent()));
        } else if (FileTypeEnum.PROPERTIES.getSubfix().equals(fileType)) {
            fileContentModReqDto.setContent(PropertiesUtil.textToContext(fileContentModReqDto.getContent()));
        } else {
        }
        configVersionService.updateContentByVersion(fileContentModReqDto);
        //改变状态
        ConfigVersion configVersion = configVersionService.findByVersion(fileContentModReqDto.getVersion());
        Config config = configService.selectConfigById(configVersion.getConfigId());
        config.setStatus(2L);
        configService.updateConfig(config);
        return ResultDto.success(null);
    }

    /**
     * 发布配置
     * 1.新配置的发布
     * 2.老配置新增版本配置的发布
     * @param versionNo
     * @return
     */
    @Override
    @Transactional
    public ResultDto releaseConfig(String versionNo) {
        ConfigVersion newVersion = configVersionService.findByVersion(versionNo);
        if (Objects.isNull(newVersion)) {
            return ResultDto.fail(GlobalExceptionEnum.NO_DATA_EXIST);
        }
        Config config = configService.selectConfigById(newVersion.getConfigId());
        if (Objects.isNull(config)) {
            return ResultDto.fail(GlobalExceptionEnum.NO_DATA_EXIST);
        }

        //新配置逻辑
        if (config.getStatus() != 3) {

            //改变状态
            config.setStatus(3L);
            configService.updateConfig(config);
        } else {
        //    老配置逻辑
            final ConfigVersion oldVersion = configVersionService.findUseVersionByConfigId(newVersion.getRoleGroup(), config.getId());

            if (Objects.nonNull(oldVersion)) {
                oldVersion.setUseStatus(2L);
                oldVersion.setUpdatedTime(new Date());
            }

        }
        newVersion.setUseStatus(1L);
        newVersion.setUpdatedTime(new Date());
        configVersionService.updateConfigVersion(newVersion);

        if (config.getBizType() != 2) {

            fileCommonAccessService.addCache(config.getId());
        }
        // 增加配置开关
        final SysTreeDict fileSwitchDict = sysTreeDictService.findFileSwitchDataByDictValue(config.getFileEnName());
        if (Objects.isNull(fileSwitchDict)) {

            DictInfoDto dictInfoDto = sysTreeDictService.findParentOneByDictValue(Constant.FILE_CONFIG_SWITCH);
            final SysTreeDict sysTreeDict = new SysTreeDict();
            sysTreeDict.setParentId(dictInfoDto.getDictId());
            sysTreeDict.setDictLabel(config.getFileZhName());
            sysTreeDict.setDictValue(config.getFileEnName());
            sysTreeDict.setDictStatus(0L);
            sysTreeDict.setCreateTime(new Date());
            sysTreeDictService.insertSysTreeDict(sysTreeDict);
        }
        return ResultDto.success(null);
    }

    /**
     * 切换文件可访问状态
     * @param configId 文件id
     * @return
     */
    @Override
    public ResultDto checkFileSwitch(Long configId) {

        final Config config = configService.selectConfigById(configId);
        if (Objects.isNull(config)) {
            return ResultDto.fail(GlobalExceptionEnum.NO_DATA_EXIST);
        }
        //切换访问状态
        final ResultDto resultDto = sysTreeDictService.checkFileSwitch(config.getFileEnName());
        // 缓存业务处理
        final SysTreeDict dictLabel = sysTreeDictService.findFileSwitchDataByDictValue(config.getFileEnName());

        if(Objects.isNull(dictLabel) || resultDto.getCode() != 0){
            return resultDto;
        }

        if (config.getBizType() != 2) {

            if (dictLabel.getDictStatus() == 1) {
                final DictInfoDto cacheDict = sysTreeDictService.findOneByDictLabel(Constant.IDAL_CACHE_FILE_PREFIX);
                final StringBuffer sb = new StringBuffer();
                sb.append(cacheDict.getDictValue()).append(config.getFileEnName()).append("*");
                fileCommonAccessService.fuzzyDelKeyAll(sb.toString());
            }else {
                fileCommonAccessService.addCache(configId);
            }
        }
        return resultDto;
    }

    @Override
    public ResultDto verifyEnNameAndRule(String fileEnName, String ruleGroup) {

        Integer count = configService.existEnNameAndRule(fileEnName,ruleGroup);
        return   count > 0 ? ResultDto.fail(GlobalExceptionEnum.EXIST_DATA):ResultDto.success(null);
    }


}


